home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / cool / cool.lha / ice / pisces / flex / misc.c < prev    next >
C/C++ Source or Header  |  1991-09-04  |  12KB  |  703 lines

  1. /* misc - miscellaneous flex routines */
  2.  
  3. /*
  4.  * Copyright (c) 1989 The Regents of the University of California.
  5.  * All rights reserved.
  6.  *
  7.  * This code is derived from software contributed to Berkeley by
  8.  * Vern Paxson.
  9.  * 
  10.  * The United States Government has rights in this work pursuant to
  11.  * contract no. DE-AC03-76SF00098 between the United States Department of
  12.  * Energy and the University of California.
  13.  *
  14.  * Redistribution and use in source and binary forms are permitted
  15.  * provided that the above copyright notice and this paragraph are
  16.  * duplicated in all such forms and that any documentation,
  17.  * advertising materials, and other materials related to such
  18.  * distribution and use acknowledge that the software was developed
  19.  * by the University of California, Berkeley.  The name of the
  20.  * University may not be used to endorse or promote products derived
  21.  * from this software without specific prior written permission.
  22.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  23.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  24.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  25.  */
  26.  
  27. #ifndef lint
  28.  
  29. static char copyright[] =
  30.     "@(#) Copyright (c) 1989 The Regents of the University of California.\n";
  31. static char CR_continuation[] = "@(#) All rights reserved.\n";
  32.  
  33. static char rcsid[] =
  34.     "@(#) $Header: /tan/u1/neath/pisces/flex/RCS/misc.c,v 1.1 90/05/15 13:13:45 neath Exp $ (LBL)";
  35.  
  36. #endif
  37.  
  38. #include <ctype.h>
  39. #include "flexdef.h"
  40.  
  41. char *malloc(), *realloc();
  42.  
  43.  
  44. /* action_out - write the actions from the temporary file to lex.yy.c
  45.  *
  46.  * synopsis
  47.  *     action_out();
  48.  *
  49.  *     Copies the action file up to %% (or end-of-file) to lex.yy.c
  50.  */
  51.  
  52. action_out()
  53.  
  54.     {
  55.     char buf[MAXLINE];
  56.  
  57.     while ( fgets( buf, MAXLINE, temp_action_file ) != NULL )
  58.     if ( buf[0] == '%' && buf[1] == '%' )
  59.         break;
  60.     else
  61.         fputs( buf, stdout );
  62.     }
  63.  
  64.  
  65. /* allocate_array - allocate memory for an integer array of the given size */
  66.  
  67. char *allocate_array( size, element_size )
  68. int size, element_size;
  69.  
  70.     {
  71.     register char *mem;
  72.  
  73.     /* on 16-bit int machines (e.g., 80286) we might be trying to
  74.      * allocate more than a signed int can hold, and that won't
  75.      * work.  Cheap test:
  76.      */
  77.     if ( element_size * size <= 0 )
  78.         flexfatal( "request for < 1 byte in allocate_array()" );
  79.     
  80.     mem = malloc( (unsigned) (element_size * size) );
  81.  
  82.     if ( mem == NULL )
  83.     flexfatal( "memory allocation failed in allocate_array()" );
  84.  
  85.     return ( mem );
  86.     }
  87.  
  88.  
  89. /* all_lower - true if a string is all lower-case
  90.  *
  91.  * synopsis:
  92.  *    char *str;
  93.  *    int all_lower();
  94.  *    true/false = all_lower( str );
  95.  */
  96.  
  97. int all_lower( str )
  98. register char *str;
  99.  
  100.     {
  101.     while ( *str )
  102.     {
  103.     if ( ! islower( *str ) )
  104.         return ( 0 );
  105.     ++str;
  106.     }
  107.  
  108.     return ( 1 );
  109.     }
  110.  
  111.  
  112. /* all_upper - true if a string is all upper-case
  113.  *
  114.  * synopsis:
  115.  *    char *str;
  116.  *    int all_upper();
  117.  *    true/false = all_upper( str );
  118.  */
  119.  
  120. int all_upper( str )
  121. register char *str;
  122.  
  123.     {
  124.     while ( *str )
  125.     {
  126.     if ( ! isupper( *str ) )
  127.         return ( 0 );
  128.     ++str;
  129.     }
  130.  
  131.     return ( 1 );
  132.     }
  133.  
  134.  
  135. /* bubble - bubble sort an integer array in increasing order
  136.  *
  137.  * synopsis
  138.  *   int v[n], n;
  139.  *   bubble( v, n );
  140.  *
  141.  * description
  142.  *   sorts the first n elements of array v and replaces them in
  143.  *   increasing order.
  144.  *
  145.  * passed
  146.  *   v - the array to be sorted
  147.  *   n - the number of elements of 'v' to be sorted */
  148.  
  149. bubble( v, n )
  150. int v[], n;
  151.  
  152.     {
  153.     register int i, j, k;
  154.  
  155.     for ( i = n; i > 1; --i )
  156.     for ( j = 1; j < i; ++j )
  157.         if ( v[j] > v[j + 1] )    /* compare */
  158.         {
  159.         k = v[j];    /* exchange */
  160.         v[j] = v[j + 1];
  161.         v[j + 1] = k;
  162.         }
  163.     }
  164.  
  165.  
  166. /* clower - replace upper-case letter to lower-case
  167.  *
  168.  * synopsis:
  169.  *    char clower(), c;
  170.  *    c = clower( c );
  171.  */
  172.  
  173. char clower( c )
  174. register char c;
  175.  
  176.     {
  177.     return ( isupper(c) ? tolower(c) : c );
  178.     }
  179.  
  180.  
  181. /* copy_string - returns a dynamically allocated copy of a string
  182.  *
  183.  * synopsis
  184.  *    char *str, *copy, *copy_string();
  185.  *    copy = copy_string( str );
  186.  */
  187.  
  188. char *copy_string( str )
  189. register char *str;
  190.  
  191.     {
  192.     register char *c;
  193.     char *copy;
  194.  
  195.     /* find length */
  196.     for ( c = str; *c; ++c )
  197.     ;
  198.  
  199.     copy = malloc( (unsigned) ((c - str + 1) * sizeof( char )) );
  200.  
  201.     if ( copy == NULL )
  202.     flexfatal( "dynamic memory failure in copy_string()" );
  203.  
  204.     for ( c = copy; (*c++ = *str++); )
  205.     ;
  206.     
  207.     return ( copy );
  208.     }
  209.  
  210.  
  211. /* cshell - shell sort a character array in increasing order
  212.  *
  213.  * synopsis
  214.  *
  215.  *   char v[n];
  216.  *   int n;
  217.  *   cshell( v, n );
  218.  *
  219.  * description
  220.  *   does a shell sort of the first n elements of array v.
  221.  *
  222.  * passed
  223.  *   v - array to be sorted
  224.  *   n - number of elements of v to be sorted
  225.  */
  226. cshell( v, n )
  227. char v[];
  228. int n;
  229.  
  230.     {
  231.     int gap, i, j, jg;
  232.     char k;
  233.  
  234.     for ( gap = n / 2; gap > 0; gap = gap / 2 )
  235.     for ( i = gap; i < n; ++i )
  236.         for ( j = i - gap; j >= 0; j = j - gap )
  237.         {
  238.         jg = j + gap;
  239.  
  240.         if ( v[j] <= v[jg] )
  241.             break;
  242.  
  243.         k = v[j];
  244.         v[j] = v[jg];
  245.         v[jg] = k;
  246.         }
  247.     }
  248.  
  249.  
  250. /* dataend - finish up a block of data declarations
  251.  *
  252.  * synopsis
  253.  *    dataend();
  254.  */
  255. dataend()
  256.  
  257.     {
  258.     if ( datapos > 0 )
  259.     dataflush();
  260.  
  261.     /* add terminator for initialization */
  262.     puts( "    } ;\n" );
  263.  
  264.     dataline = 0;
  265.     }
  266.  
  267.  
  268.  
  269. /* dataflush - flush generated data statements
  270.  *
  271.  * synopsis
  272.  *    dataflush();
  273.  */
  274. dataflush()
  275.  
  276.     {
  277.     putchar( '\n' );
  278.  
  279.     if ( ++dataline >= NUMDATALINES )
  280.     {
  281.     /* put out a blank line so that the table is grouped into
  282.      * large blocks that enable the user to find elements easily
  283.      */
  284.     putchar( '\n' );
  285.     dataline = 0;
  286.     }
  287.  
  288.     /* reset the number of characters written on the current line */
  289.     datapos = 0;
  290.     }
  291.  
  292. /* flex_gettime - return current time
  293.  *
  294.  * synopsis
  295.  *    char *flex_gettime(), *time_str;
  296.  *    time_str = flex_gettime();
  297.  *
  298.  * note
  299.  *    the routine name has the "flex_" prefix because of name clashes
  300.  *    with Turbo-C
  301.  */
  302.  
  303. /* include sys/types.h to use time_t and make lint happy */
  304.  
  305. #ifndef MS_DOS
  306. #ifndef VMS
  307. #include <sys/types.h>
  308. #else
  309. #include <types.h>
  310. #endif
  311. #endif
  312.  
  313. #ifdef MS_DOS
  314. #include <time.h>
  315. typedef long time_t;
  316. #endif
  317.  
  318. char *flex_gettime()
  319.  
  320.     {
  321.     time_t t, time();
  322.     char *result, *ctime(), *copy_string();
  323.  
  324.     t = time( (long *) 0 );
  325.  
  326.     result = copy_string( ctime( &t ) );
  327.  
  328.     /* get rid of trailing newline */
  329.     result[24] = '\0';
  330.  
  331.     return ( result );
  332.     }
  333.  
  334.  
  335. /* lerrif - report an error message formatted with one integer argument
  336.  *
  337.  * synopsis
  338.  *    char msg[];
  339.  *    int arg;
  340.  *    lerrif( msg, arg );
  341.  */
  342.  
  343. lerrif( msg, arg )
  344. char msg[];
  345. int arg;
  346.  
  347.     {
  348.     char errmsg[MAXLINE];
  349.     (void) sprintf( errmsg, msg, arg );
  350.     flexerror( errmsg );
  351.     }
  352.  
  353.  
  354. /* lerrsf - report an error message formatted with one string argument
  355.  *
  356.  * synopsis
  357.  *    char msg[], arg[];
  358.  *    lerrsf( msg, arg );
  359.  */
  360.  
  361. lerrsf( msg, arg )
  362. char msg[], arg[];
  363.  
  364.     {
  365.     char errmsg[MAXLINE];
  366.  
  367.     (void) sprintf( errmsg, msg, arg );
  368.     flexerror( errmsg );
  369.     }
  370.  
  371.  
  372. /* flexerror - report an error message and terminate
  373.  *
  374.  * synopsis
  375.  *    char msg[];
  376.  *    flexerror( msg );
  377.  */
  378.  
  379. flexerror( msg )
  380. char msg[];
  381.  
  382.     {
  383.     fprintf( stderr, "flex: %s\n", msg );
  384.  
  385.     flexend( 1 );
  386.     }
  387.  
  388.  
  389. /* flexfatal - report a fatal error message and terminate
  390.  *
  391.  * synopsis
  392.  *    char msg[];
  393.  *    flexfatal( msg );
  394.  */
  395.  
  396. flexfatal( msg )
  397. char msg[];
  398.  
  399.     {
  400.     fprintf( stderr, "flex: fatal internal error %s\n", msg );
  401.     flexend( 1 );
  402.     }
  403.  
  404.  
  405. /* line_directive_out - spit out a "# line" statement */
  406.  
  407. line_directive_out( output_file_name )
  408. FILE *output_file_name;
  409.  
  410.     {
  411.     if ( infilename && gen_line_dirs ) 
  412.         fprintf( output_file_name, "# line %d \"%s\"\n", linenum, infilename );
  413.     }
  414.  
  415.  
  416. /* mk2data - generate a data statement for a two-dimensional array
  417.  *
  418.  * synopsis
  419.  *    int value;
  420.  *    mk2data( value );
  421.  *
  422.  *  generates a data statement initializing the current 2-D array to "value"
  423.  */
  424. mk2data( value )
  425. int value;
  426.  
  427.     {
  428.     if ( datapos >= NUMDATAITEMS )
  429.     {
  430.     putchar( ',' );
  431.     dataflush();
  432.     }
  433.  
  434.     if ( datapos == 0 )
  435.     /* indent */
  436.     fputs( "    ", stdout );
  437.  
  438.     else
  439.     putchar( ',' );
  440.  
  441.     ++datapos;
  442.  
  443.     printf( "%5d", value );
  444.     }
  445.  
  446.  
  447. /* mkdata - generate a data statement
  448.  *
  449.  * synopsis
  450.  *    int value;
  451.  *    mkdata( value );
  452.  *
  453.  *  generates a data statement initializing the current array element to
  454.  *  "value"
  455.  */
  456. mkdata( value )
  457. int value;
  458.  
  459.     {
  460.     if ( datapos >= NUMDATAITEMS )
  461.     {
  462.     putchar( ',' );
  463.     dataflush();
  464.     }
  465.  
  466.     if ( datapos == 0 )
  467.     /* indent */
  468.     fputs( "    ", stdout );
  469.  
  470.     else
  471.     putchar( ',' );
  472.  
  473.     ++datapos;
  474.  
  475.     printf( "%5d", value );
  476.     }
  477.  
  478.  
  479. /* myctoi - return the integer represented by a string of digits
  480.  *
  481.  * synopsis
  482.  *    char array[];
  483.  *    int val, myctoi();
  484.  *    val = myctoi( array );
  485.  *
  486.  */
  487.  
  488. int myctoi( array )
  489. char array[];
  490.  
  491.     {
  492.     int val = 0;
  493.  
  494.     (void) sscanf( array, "%d", &val );
  495.  
  496.     return ( val );
  497.     }
  498.  
  499.  
  500. /* myesc - return character corresponding to escape sequence
  501.  *
  502.  * synopsis
  503.  *    char array[], c, myesc();
  504.  *    c = myesc( array );
  505.  *
  506.  */
  507.  
  508. char myesc( array )
  509. char array[];
  510.  
  511.     {
  512.     switch ( array[1] )
  513.     {
  514.     case 'a': return ( '\a' );
  515.     case 'b': return ( '\b' );
  516.     case 'f': return ( '\f' );
  517.     case 'n': return ( '\n' );
  518.     case 'r': return ( '\r' );
  519.     case 't': return ( '\t' );
  520.     case 'v': return ( '\v' );
  521.  
  522.     case '0':
  523.     case '1':
  524.     case '2':
  525.     case '3':
  526.     case '4':
  527.     case '5':
  528.     case '6':
  529.     case '7':
  530.     case '8':
  531.     case '9':
  532.         { /* \<octal> */
  533.         char c, esc_char;
  534.         register int sptr = 1;
  535.  
  536.         while ( isdigit(array[sptr]) )
  537.         /* don't increment inside loop control because if
  538.          * isdigit() is a macro it will expand it to two
  539.          * increments ...
  540.          */
  541.         ++sptr;
  542.  
  543.         c = array[sptr];
  544.         array[sptr] = '\0';
  545.  
  546.         esc_char = otoi( array + 1 );
  547.         array[sptr] = c;
  548.  
  549.         if ( esc_char == '\0' )
  550.         {
  551.         synerr( "escape sequence for null not allowed" );
  552.         return ( 1 );
  553.         }
  554.  
  555.         return ( esc_char );
  556.         }
  557.  
  558.     default:
  559.         return ( array[1] );
  560.     }
  561.     }
  562.  
  563.  
  564. /* otoi - convert an octal digit string to an integer value
  565.  *
  566.  * synopsis:
  567.  *    int val, otoi();
  568.  *    char str[];
  569.  *    val = otoi( str );
  570.  */
  571.  
  572. int otoi( str )
  573. char str[];
  574.  
  575.     {
  576.     int result;
  577.  
  578.     (void) sscanf( str, "%o", &result );
  579.  
  580.     return ( result );
  581.     }
  582.  
  583.  
  584. /* readable_form - return the the human-readable form of a character
  585.  *
  586.  * synopsis:
  587.  *    int c;
  588.  *    char *readable_form();
  589.  *    <string> = readable_form( c );
  590.  *
  591.  * The returned string is in static storage.
  592.  */
  593.  
  594. char *readable_form( c )
  595. register int c;
  596.  
  597.     {
  598.     static char rform[10];
  599.  
  600.     if ( (c >= 0 && c < 32) || c == 127 )
  601.     {
  602.     switch ( c )
  603.         {
  604.         case '\n': return ( "\\n" );
  605.         case '\t': return ( "\\t" );
  606.         case '\f': return ( "\\f" );
  607.         case '\r': return ( "\\r" );
  608.         case '\b': return ( "\\b" );
  609.  
  610.         default:
  611.         sprintf( rform, "\\%.3o", c );
  612.         return ( rform );
  613.         }
  614.     }
  615.     
  616.     else if ( c == ' ' )
  617.     return ( "' '" );
  618.     
  619.     else
  620.     {
  621.     rform[0] = c;
  622.     rform[1] = '\0';
  623.  
  624.     return ( rform );
  625.     }
  626.     }
  627.  
  628.  
  629. /* reallocate_array - increase the size of a dynamic array */
  630.  
  631. char *reallocate_array( array, size, element_size )
  632. char *array;
  633. int size, element_size;
  634.  
  635.     {
  636.     register char *new_array;
  637.  
  638.     /* same worry as in allocate_array(): */
  639.     if ( size * element_size <= 0 )
  640.         flexfatal( "attempt to increase array size by less than 1 byte" );
  641.     
  642.     new_array = realloc( array, (unsigned) (size * element_size ));
  643.  
  644.     if ( new_array == NULL )
  645.     flexfatal( "attempt to increase array size failed" );
  646.     
  647.     return ( new_array );
  648.     }
  649.  
  650.  
  651. /* skelout - write out one section of the skeleton file
  652.  *
  653.  * synopsis
  654.  *    skelout();
  655.  *
  656.  * DESCRIPTION
  657.  *    Copies from skelfile to stdout until a line beginning with "%%" or
  658.  *    EOF is found.
  659.  */
  660. skelout()
  661.  
  662.     {
  663.     char buf[MAXLINE];
  664.  
  665.     while ( fgets( buf, MAXLINE, skelfile ) != NULL )
  666.     if ( buf[0] == '%' && buf[1] == '%' )
  667.         break;
  668.     else
  669.         fputs( buf, stdout );
  670.     }
  671.  
  672.  
  673. /* transition_struct_out - output a yy_trans_info structure
  674.  *
  675.  * synopsis
  676.  *     int element_v, element_n;
  677.  *     transition_struct_out( element_v, element_n );
  678.  *
  679.  * outputs the yy_trans_info structure with the two elements, element_v and
  680.  * element_n.  Formats the output with spaces and carriage returns.
  681.  */
  682.  
  683. transition_struct_out( element_v, element_n )
  684. int element_v, element_n;
  685.  
  686.     {
  687.     printf( "%7d, %5d,", element_v, element_n );
  688.  
  689.     datapos += TRANS_STRUCT_PRINT_LENGTH;
  690.  
  691.     if ( datapos >= 75 )
  692.     {
  693.     putchar( '\n' );
  694.  
  695.     if ( ++dataline % 10 == 0 )
  696.         putchar( '\n' );
  697.  
  698.     datapos = 0;
  699.     }
  700.     }
  701.  
  702.  
  703.